package com.two.screen.water.balance.serial.card

import android.os.SystemClock
import com.cyItem.sesrialPort.SerialPort
import com.cyItem.sesrialPort.SerialPortFinder
import com.two.screen.water.balance.listener.ReadCardCallBack
import com.two.screen.water.balance.utils.ByteUtils
import com.two.screen.water.balance.utils.CommUtils
import io.reactivex.Observable
import io.reactivex.ObservableEmitter
import io.reactivex.ObservableOnSubscribe
import io.reactivex.Observer
import io.reactivex.disposables.Disposable
import java.io.File
import java.io.InputStream
import java.util.concurrent.TimeUnit


object SerialPortReadCardAllZzUtils {
    private var mSerialPort: SerialPort? = null
    private var mInputStream: InputStream? = null
    private var mReadCardThread: Thread? = null
    private var mDevicePathArray: Array<String>? = null
    private var mDevicePath: String? = null
    private var mSerialPortPath = "/dev/ttyS0"
    private var mSerialPortPort = 9600

    private var mAskBlock04Emitter: ObservableEmitter<String>? = null
    private var mPollingAskBlock04Disposable: Disposable? = null
    private var mPollingAskBlock04Disposable1: Disposable? = null

    fun initSerialPortBattery() {
        close()
        mSerialPortPath = "/dev/ttyS0"
        mDevicePathArray = SerialPortFinder().allDevicesPath

        if (mDevicePathArray == null || mDevicePathArray!!.isEmpty()) {
            return
        }
        mDevicePathArray?.forEach {
            if (mSerialPortPath == it) {
                mDevicePath = it
            }
            d("串口：$it")
        }
        d("串口：确认：$mDevicePath")
        if (mDevicePath.isNullOrBlank()) {
            return
        }

        mSerialPort = try {
            SerialPort(File(mSerialPortPath), mSerialPortPort, 0)
        } catch (e: Exception) {
            d("串口通信失败，请重试！")
            closeSerialPort()
            return
        }

        mInputStream = mSerialPort?.inputStream
        if (mInputStream == null) {
            d("电子秤端口或者波特率未正确配置！")
            closeSerialPort()
            return
        }
        mReadCardThread = ReadCardThread()
        mReadCardThread!!.start()
    }

    fun close() {
        closeThreadQuiet()
        closeSerialPort()
    }

    //关闭线程
    private fun closeThreadQuiet() {
        if (mReadCardThread != null) {
            try {
                mReadCardThread?.interrupt()
            } catch (e: java.lang.Exception) {
                // just ignore
            } finally {
                mReadCardThread = null
            }
        }
    }

    //关闭串口
    private fun closeSerialPort() {
        if (mSerialPort != null) {
            try {
                if (mInputStream != null) {
                    mInputStream!!.close()
                }
            } catch (e: java.lang.Exception) {
                e.printStackTrace()
            }
            if (mSerialPort!!.isOpen) {
                mSerialPort!!.closePort()
            }
            mSerialPort = null
        }
    }

    private fun sendReceive(msg: String, r: ReadCardCallBack? = null) {
        d("send Hex:$msg")
        mSerialPort?.outputStream?.write(ByteUtils.hexStr2Bytes(msg))
        SystemClock.sleep(500)
        var response = ByteArray(maxSize)
        val len = mInputStream?.read(response) ?: 0
        //d("len:$len")
        if (len < 1) return
        response = response.dropLast(maxSize - len).toByteArray()
        val hexString = ByteUtils.bytes2HexStr(response).uppercase()
        r?.success(hexString)
    }

    private var maxSize = 32

    internal class ReadCardThread : Thread() {
        override fun run() {
            //发送 keyA
            SystemClock.sleep(1000)
            sendReceive("20004C08000F020000000103B403", object : ReadCardCallBack {
                //keyA
                override fun success(t: String?) {
                    if ("20000000FF03" == t) d("加载KeyA成功:$t")
                    else onError(t, "加载KeyA失败")
                }
            })

            while (true) {
                try {
                    //存在中断就退出。
                    if (isInterrupted) break
                    sendReceive("20005200AD03", object : ReadCardCallBack {
                        //初始化模块
                        override fun success(t: String?) {
                            d("receive Hex:$t")
                            if ("20000000FF03" == t) {
                                d("读卡器模块初始化成功:$t")
                                sendReceive("2000100100EE03", object : ReadCardCallBack {
                                    //激活卡
                                    override fun success(t: String?) {
                                        d("receive Hex:$t")
                                        if (t?.startsWith("20000008") == true) {
                                            d("激活卡成功:$t")
                                            sendReceive("20001203000f04E503", object : ReadCardCallBack {
                                                //寻卡block04
                                                override fun success(t: String?) {
                                                    d("receive Hex:$t")
                                                    if (t?.startsWith("20000010") == true) {

                                                        d("寻卡block04成功:${t.subSequence(8, t.length - 4)}")
                                                        //TODO:

                                                        SystemClock.sleep(20000)
                                                    } else {
                                                        onError(t, "寻卡block04失败")
                                                    }
                                                }
                                            })
                                        } else {
                                            onError(t, "激活失败")
                                        }
                                    }
                                })
                            } else {
                                onError(t, "读卡器模块初始化失败")
                            }
                        }
                    })

                } catch (e: Exception) {
                    d("ReadCardThread:$e")
                }
            }
        }
    }

    private fun onError(hexCode: String?, tips: String? = null) {
        var errorCode = hexCode?.substring(4, 6)

        when (errorCode) {
            "01" -> d("在有效区域内没有卡,$hexCode")
            "1B" -> d("访问超时,$hexCode")
            "09" -> d("证实密码错,$hexCode")
            "0A" -> d("卡没有验证,$hexCode")
            else -> d("${tips ?: "未知错误"}:$hexCode,errorCode:$errorCode")
        }
    }


    fun d(msg: String) {
        CommUtils.println("SerialPortReadCardZzUtils->", msg)
    }
}